package com.lcf.app.websocket.socket;

import com.alibaba.fastjson.JSON;
import com.lcf.app.websocket.model.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 功能描述：
 *
 * @Return:
 * @Author: ChenFei
 * @Date: 2021/11/1
 * @Description:
 */
@Slf4j
@Component
@ServerEndpoint(value = "/ws/{id}")
public class WebSocketServer {

    /**
     * 功能描述：用来记录当前链接websocket的客户端，一个session相当于一个用户
     */
    private static Map<String, Session> sessionMap = new ConcurrentHashMap<>(10);

    /**
     * 功能描述：建立链接调用
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "id") String id) throws IOException {
        log.info("onOpen => id : {}", id);
        sessionMap.put(id, session);
    }

    /**
     * 功能描述：关闭链接调用
     */
    @OnClose
    public void onClose(@PathParam(value = "id") String id) {
        log.info("onClose => id : {}", id);
        sessionMap.remove(id);
    }

    /**
     * 功能描述：收到客户端的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam(value = "id") String id) {
        log.info("onMessage => id : {} , message : {}", id, message);
        sendMessageAll(JSON.toJSONString(new Message().setId(id).setMessage(message)));
    }

    @OnError
    public void onError(Throwable throwable) {
        log.error("webSocket error : {}", throwable);
    }

    /**
     * 功能描述：根据ID发送message
     */
    public void sendMessage(String id, String message) {
        Optional.ofNullable(sessionMap.get(id))
                .ifPresent(session -> session
                        .getAsyncRemote()
                        .sendText(JSON.toJSONString(new Message()
                                .setId(id)
                                .setMessage(message))));
    }

    /**
     * 功能描述：发送给所有
     */
    public void sendMessageAll(String message) {
        sessionMap.forEach((id, session) -> session.getAsyncRemote().sendText(message));
    }
}
